Fabricjs 作為了個已經出來了將近 10 年的 library (from 2008),也就是 ie 還盛行的年代,經歷 web 前端技術改變的考驗,到 2018 還是不停在更新著。
既然在十年前就能使用這個 Library 了,過了十年硬體設備更強大的情況下,跑起來效能絕對不是問題,或許是因為 Fabricjs 原本定位就不再做出很炫很複雜的動畫效果,而是在於和使用者的互動上。
2.0.0
版本之後,圖片的濾鏡就能夠使用 WEBGL
來做渲染,對於圖片濾鏡的操作效能也是一大提升。
2018/11/11 截圖 - fabricjs github
不過可惜的是繪製圖形還不支援 WEBGL
比較沒辦法及時刷新更多的圖形做粒子動畫。
來看看如何調整 Fabricjs 的運作效能。
一般使用 Fabricjs 來繪製一些簡單圖片和 2D 形狀是沒有甚麼問題的。
參考 fabricjs demo - particles 繪製一千顆粒子
以及參考官方 demo 做的 10000 顆粒子 codepen
當我們在做大量新增或刪除時,並不想要每次新增一個圖形就自動重新刷新一次畫布,所以可以將 canvas.renderOnAddRemove
設為 false
但是在大量 canvas.add()
之後,需要做一次 canvas.renderAll()
來統一刷新畫布。
var canvas2 = new fabric.Canvas('c2', { backgroundColor: "#000", renderOnAddRemove: false })
...省略
for (i = 10000; i >= 0; i--) {
dot = new fabric.Circle({
left: getRandomInt(0, 400),
top: getRandomInt(0, 350),
radius: 3,
fill: rainbow[getRandomInt(0, rainbowEnd)],
objectCaching: false
});
canvas2.add(dot);
}
canvas2.renderAll(); // 必要
物件快取在 Fabricjs 1.7.0 之後才有的功能,預設為 true
,啟用了這個物件快取後,會產生一個和你的物件一樣的 Image 在你看不見的地方,在你做旋轉、縮放、移動...等動作時,會使用 canvas 的 drawImage 來畫出圖形。
這樣有什麼好處呢?
若是在處理像是 SVG 這樣有複雜節點的圖形,每次做旋轉、縮放那些動作等於又重新要計算一次所有節點,運算起來是相當複雜又耗時的,所以 Fabricjs 提供了這個方法,使用 drawImage 指畫出整個圖形,就不用再讓電腦重複計算複雜路徑。
可以看看以下官方提供的範例,處理一個幾萬個 Path 的複雜 svg。
可以看到左邊非常的順暢,而右邊沒有快取卡到連動都動不了...
左邊黃色車子設定 objectCaching = true
右邊為 false
fabricjs 會在 mouseup
產生新的物件快取圖片。
所以在將小的物件變大時,會看到你的圖形是模糊的。
當然要不要使用 objectChaching
是可以選擇的,當圖形為簡單不複雜的形狀時,當然也是可以將 objectChaching
設為 false
。
其他關於物件快取的範例
Text performance
svg cache
這邊 Fabricjs wiki 提供了一些效能調整的選項。
其實整體來說就是:
以效能渲染來說
Fabricjs 和現今其他主流 Canvas Library比較起來,以使用定位來說,對動畫效能沒有太多的優化,但是在 svg 圖形路徑上優化是還不錯的。
再不做太大量物件渲染上 (10000 object up),操作起來都是順暢的。